package com.jevons.muffin.net.bean;

import androidx.annotation.Nullable;


import com.jevons.muffin.net.inter.UploadFileObserver;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * 文件上传请求体，使其显示上传进度
 * power by https://www.jianshu.com/p/abbf3410962e
 * @author linaisheng
 * Created at 2019/4/11.
 */

public class UploadFileRequestBody extends RequestBody {

    private RequestBody mRequestBody;
    private UploadFileObserver<RequestBody> uploadFileObserver;

    public UploadFileRequestBody(RequestBody requestBody, UploadFileObserver<RequestBody> uploadFileObserver) {
        this.mRequestBody = requestBody;
        this.uploadFileObserver = uploadFileObserver;

    }

    @Nullable
    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

    @Override
    public long contentLength() throws IOException {
        return mRequestBody.contentLength();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CountingSink countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(countingSink);
        //写入
        mRequestBody.writeTo(bufferedSink);
        //必须调用flush，否则最后一部分数据可能不会被写入
        bufferedSink.flush();
    }

    protected final class CountingSink extends ForwardingSink {

        private long bytesWritten = 0;

        public CountingSink(Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);

            bytesWritten += byteCount;
            if (uploadFileObserver != null) {
                //通知进度
                uploadFileObserver.onProgressChange(bytesWritten, contentLength());
            }
        }
    }

}
